home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / WarpQuake / Src / d_scan.c < prev    next >
C/C++ Source or Header  |  2000-05-22  |  18KB  |  753 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // d_scan.c
  21. //
  22. // Portable C scan-level rasterization code, all pixel depths.
  23.  
  24. #include "quakedef.h"
  25. #include "r_local.h"
  26. #include "d_local.h"
  27.  
  28. unsigned char    *r_turb_pbase, *r_turb_pdest;
  29. fixed16_t        r_turb_s, r_turb_t, r_turb_sstep, r_turb_tstep;
  30. int                *r_turb_turb;
  31. int                r_turb_spancount;
  32.  
  33. void D_DrawTurbulent8Span (void);
  34.  
  35.  
  36. #if !id68k
  37. /*
  38. =============
  39. D_WarpScreen
  40.  
  41. // this performs a slight compression of the screen at the same time as
  42. // the sine warp, to keep the edges from wrapping
  43. =============
  44. */
  45. void D_WarpScreen (void)
  46. {
  47.     int        w, h;
  48.     int        u,v;
  49.     byte    *dest;
  50.     int        *turb;
  51.     int        *col;
  52.     byte    **row;
  53.     byte    *rowptr[MAXHEIGHT+(AMP2*2)];
  54.     int        column[MAXWIDTH+(AMP2*2)];
  55.     float    wratio, hratio;
  56.  
  57.     w = r_refdef.vrect.width;
  58.     h = r_refdef.vrect.height;
  59.  
  60.     wratio = w / (float)scr_vrect.width;
  61.     hratio = h / (float)scr_vrect.height;
  62.  
  63.     for (v=0 ; v<scr_vrect.height+AMP2*2 ; v++)
  64.     {
  65.         rowptr[v] = d_viewbuffer + (r_refdef.vrect.y * screenwidth) +
  66.                  (screenwidth * (int)((float)v * hratio * h / (h + AMP2 * 2)));
  67.     }
  68.  
  69.     for (u=0 ; u<scr_vrect.width+AMP2*2 ; u++)
  70.     {
  71.         column[u] = r_refdef.vrect.x +
  72.                 (int)((float)u * wratio * w / (w + AMP2 * 2));
  73.     }
  74.  
  75.     turb = intsintable + ((int)(cl.time*SPEED)&(CYCLE-1));
  76.     dest = vid.buffer + scr_vrect.y * vid.rowbytes + scr_vrect.x;
  77.  
  78.     for (v=0 ; v<scr_vrect.height ; v++, dest += vid.rowbytes)
  79.     {
  80.         col = &column[turb[v]];
  81.         row = &rowptr[v];
  82.  
  83.         for (u=0 ; u<scr_vrect.width ; u+=4)
  84.         {
  85.             dest[u+0] = row[turb[u+0]][col[u+0]];
  86.             dest[u+1] = row[turb[u+1]][col[u+1]];
  87.             dest[u+2] = row[turb[u+2]][col[u+2]];
  88.             dest[u+3] = row[turb[u+3]][col[u+3]];
  89.         }
  90.     }
  91. }
  92.  
  93. #endif
  94.  
  95. #if    !id386
  96. #if !id68k
  97.  
  98. /*
  99. =============
  100. D_DrawTurbulent8Span
  101. =============
  102. */
  103. void D_DrawTurbulent8Span (void)
  104. {
  105.     int        sturb, tturb;
  106.  
  107.     do
  108.     {
  109.         sturb = ((r_turb_s + r_turb_turb[(r_turb_t>>16)&(CYCLE-1)])>>16)&63;
  110.         tturb = ((r_turb_t + r_turb_turb[(r_turb_s>>16)&(CYCLE-1)])>>16)&63;
  111.         *r_turb_pdest++ = *(r_turb_pbase + (tturb<<6) + sturb);
  112.         r_turb_s += r_turb_sstep;
  113.         r_turb_t += r_turb_tstep;
  114.     } while (--r_turb_spancount > 0);
  115. }
  116.  
  117. #endif
  118. #endif    // !id386
  119.  
  120.  
  121. #if !id68k
  122. /*
  123. =============
  124. Turbulent8
  125. =============
  126. */
  127. void Turbulent8 (espan_t *pspan)
  128. {
  129.     int                count;
  130.     fixed16_t        snext, tnext;
  131.     float            sdivz, tdivz, zi, z, du, dv, spancountminus1;
  132.     float            sdivz16stepu, tdivz16stepu, zi16stepu;
  133.     
  134.     r_turb_turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1));
  135.  
  136.     r_turb_sstep = 0;    // keep compiler happy
  137.     r_turb_tstep = 0;    // ditto
  138.  
  139.     r_turb_pbase = (unsigned char *)cacheblock;
  140.  
  141.     sdivz16stepu = d_sdivzstepu * 16;
  142.     tdivz16stepu = d_tdivzstepu * 16;
  143.     zi16stepu = d_zistepu * 16;
  144.  
  145.     do
  146.     {
  147.         r_turb_pdest = (unsigned char *)((byte *)d_viewbuffer +
  148.                 (screenwidth * pspan->v) + pspan->u);
  149.  
  150.         count = pspan->count;
  151.  
  152.     // calculate the initial s/z, t/z, 1/z, s, and t and clamp
  153.         du = (float)pspan->u;
  154.         dv = (float)pspan->v;
  155.  
  156.         sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
  157.         tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
  158.         zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
  159.         z = (float)0x10000 / zi;    // prescale to 16.16 fixed-point
  160.  
  161.         r_turb_s = (int)(sdivz * z) + sadjust;
  162.         if (r_turb_s > bbextents)
  163.             r_turb_s = bbextents;
  164.         else if (r_turb_s < 0)
  165.             r_turb_s = 0;
  166.  
  167.         r_turb_t = (int)(tdivz * z) + tadjust;
  168.         if (r_turb_t > bbextentt)
  169.             r_turb_t = bbextentt;
  170.         else if (r_turb_t < 0)
  171.             r_turb_t = 0;
  172.  
  173.         do
  174.         {
  175.         // calculate s and t at the far end of the span
  176.             if (count >= 16)
  177.                 r_turb_spancount = 16;
  178.             else
  179.                 r_turb_spancount = count;
  180.  
  181.             count -= r_turb_spancount;
  182.  
  183.             if (count)
  184.             {
  185.             // calculate s/z, t/z, zi->fixed s and t at far end of span,
  186.             // calculate s and t steps across span by shifting
  187.                 sdivz += sdivz16stepu;
  188.                 tdivz += tdivz16stepu;
  189.                 zi += zi16stepu;
  190.                 z = (float)0x10000 / zi;    // prescale to 16.16 fixed-point
  191.  
  192.                 snext = (int)(sdivz * z) + sadjust;
  193.                 if (snext > bbextents)
  194.                     snext = bbextents;
  195.                 else if (snext < 16)
  196.                     snext = 16;    // prevent round-off error on <0 steps from
  197.                                 //  from causing overstepping & running off the
  198.                                 //  edge of the texture
  199.  
  200.                 tnext = (int)(tdivz * z) + tadjust;
  201.                 if (tnext > bbextentt)
  202.                     tnext = bbextentt;
  203.                 else if (tnext < 16)
  204.                     tnext = 16;    // guard against round-off error on <0 steps
  205.  
  206.                 r_turb_sstep = (snext - r_turb_s) >> 4;
  207.                 r_turb_tstep = (tnext - r_turb_t) >> 4;
  208.             }
  209.             else
  210.             {
  211.             // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
  212.             // can't step off polygon), clamp, calculate s and t steps across
  213.             // span by division, biasing steps low so we don't run off the
  214.             // texture
  215.                 spancountminus1 = (float)(r_turb_spancount - 1);
  216.                 sdivz += d_sdivzstepu * spancountminus1;
  217.                 tdivz += d_tdivzstepu * spancountminus1;
  218.                 zi += d_zistepu * spancountminus1;
  219.                 z = (float)0x10000 / zi;    // prescale to 16.16 fixed-point
  220.                 snext = (int)(sdivz * z) + sadjust;
  221.                 if (snext > bbextents)
  222.                     snext = bbextents;
  223.                 else if (snext < 16)
  224.                     snext = 16;    // prevent round-off error on <0 steps from
  225.                                 //  from causing overstepping & running off the
  226.                                 //  edge of the texture
  227.  
  228.                 tnext = (int)(tdivz * z) + tadjust;
  229.                 if (tnext > bbextentt)
  230.                     tnext = bbextentt;
  231.                 else if (tnext < 16)
  232.                     tnext = 16;    // guard against round-off error on <0 steps
  233.  
  234.                 if (r_turb_spancount > 1)
  235.                 {
  236.                     r_turb_sstep = (snext - r_turb_s) / (r_turb_spancount - 1);
  237.                     r_turb_tstep = (tnext - r_turb_t) / (r_turb_spancount - 1);
  238.                 }
  239.             }
  240.  
  241.             r_turb_s = r_turb_s & ((CYCLE<<16)-1);
  242.             r_turb_t = r_turb_t & ((CYCLE<<16)-1);
  243.  
  244.             D_DrawTurbulent8Span ();
  245.  
  246.             r_turb_s = snext;
  247.             r_turb_t = tnext;
  248.  
  249.         } while (count > 0);
  250.  
  251.     } while ((pspan = pspan->pnext) != NULL);
  252. }
  253.  
  254. #endif
  255.  
  256. #if    !id386
  257. //#if    !idppc
  258. #if !id68k
  259.  
  260.  
  261. /*
  262. =============
  263. D_DrawSpans8
  264. =============
  265. */
  266. void D_DrawSpans8 (espan_t *pspan)
  267. {
  268.     int                count, spancount, copy_of_cachewidth;
  269.     unsigned char    *pbase, *pdest;
  270.     fixed16_t        s, t, snext, tnext, sstep, tstep;
  271.     float            sdivz, tdivz, zi, z, du, dv, spancountminus1;
  272.     float            sdivz8stepu, tdivz8stepu, zi8stepu;
  273.  
  274.     sstep = 0;    // keep compiler happy
  275.     tstep = 0;    // ditto
  276.  
  277.     pbase = (unsigned char *)cacheblock;
  278.  
  279.     sdivz8stepu = d_sdivzstepu * 8;
  280.     tdivz8stepu = d_tdivzstepu * 8;
  281.     zi8stepu = d_zistepu * 8;
  282.  
  283.     do
  284.     {
  285.         pdest = (unsigned char *)((byte *)d_viewbuffer +
  286.                 (screenwidth * pspan->v) + pspan->u);
  287.  
  288.         count = pspan->count;
  289.  
  290.     // calculate the initial s/z, t/z, 1/z, s, and t and clamp
  291.         du = (float)pspan->u;
  292.         dv = (float)pspan->v;
  293.  
  294.         sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
  295.         tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
  296.         zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
  297.         z = (float)0x10000 / zi;    // prescale to 16.16 fixed-point
  298.  
  299.         s = (int)(sdivz * z) + sadjust;
  300.         if (s > bbextents)
  301.             s = bbextents;
  302.         else if (s < 0)
  303.             s = 0;
  304.  
  305.         t = (int)(tdivz * z) + tadjust;
  306.         if (t > bbextentt)
  307.             t = bbextentt;
  308.         else if (t < 0)
  309.             t = 0;
  310.  
  311.         if (count > 8)
  312.             zi += zi8stepu;
  313.         else {
  314.             spancountminus1 = (float)(count - 1);
  315.             zi += d_zistepu * spancountminus1;
  316.         }
  317.         z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
  318.  
  319.         do
  320.         {
  321.         // calculate s and t at the far end of the span
  322.             if (count >= 8)
  323.                 spancount = 8;
  324.             else
  325.                 spancount = count;
  326.  
  327.             count -= spancount;
  328.  
  329.             if (count)
  330.             {
  331.             // calculate s/z, t/z, zi->fixed s and t at far end of span,
  332.             // calculate s and t steps across span by shifting
  333.                 sdivz += sdivz8stepu;
  334.                 tdivz += tdivz8stepu;
  335.                 snext = (int)(sdivz * z) + sadjust;
  336.                 tnext = (int)(tdivz * z) + tadjust;
  337.                 if (count > 8)
  338.                     zi += zi8stepu;
  339.                 else {
  340.                     spancountminus1 = (float)(count - 1);
  341.                     zi += d_zistepu * spancountminus1;
  342.                 }
  343.                 z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
  344.                 if (snext > bbextents)
  345.                     snext = bbextents;
  346.                 else if (snext < 8)
  347.                     snext = 8; // prevent round-off error on <0 steps from
  348.                            //  from causing overstepping & running off the
  349.                            //  edge of the texture
  350.  
  351.                 if (tnext > bbextentt)
  352.                     tnext = bbextentt;
  353.                 else if (tnext < 8)
  354.                     tnext = 8; // guard against round-off error on <0 steps
  355.  
  356.                 sstep = (snext - s) >> 3;
  357.                 tstep = (tnext - t) >> 3;
  358.             }
  359.             else
  360.             {
  361.             // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
  362.             // can't step off polygon), clamp, calculate s and t steps across
  363.             // span by division, biasing steps low so we don't run off the
  364.             // texture
  365.                 sdivz += d_sdivzstepu * spancountminus1;
  366.                 tdivz += d_tdivzstepu * spancountminus1;
  367.  
  368.                 snext = (int)(sdivz * z) + sadjust;
  369.                 tnext = (int)(tdivz * z) + tadjust;
  370.  
  371.                 if (snext > bbextents)
  372.                     snext = bbextents;
  373.                 else if (snext < 8)
  374.                     snext = 8; // prevent round-off error on <0 steps from
  375.                            //  from causing overstepping & running off the
  376.                            //  edge of the texture
  377.                 if (tnext > bbextentt)
  378.  
  379.                     tnext = bbextentt;
  380.                 else if (tnext < 8)
  381.                     tnext = 8; // guard against round-off error on <0 steps
  382.  
  383.                 if (spancount > 1)
  384.                 {
  385.                     sstep = (snext - s) / (spancount - 1);
  386.                     tstep = (tnext - t) / (spancount - 1);
  387.                 }
  388.             }
  389.  
  390.             copy_of_cachewidth = cachewidth;
  391. #if 1
  392.             do
  393.             {
  394.                 *pdest++ = *(pbase + (s >> 16) + (t >> 16) * copy_of_cachewidth);
  395.                 s += sstep;
  396.                 t += tstep;
  397.             } while (--spancount > 0);
  398. #else
  399.             switch (((unsigned long)pdest) & 3) {
  400.             case 1:
  401.                 *pdest++ = *(pbase + (s >> 16) + (t >> 16) * copy_of_cachewidth);
  402.                 s += sstep;
  403.                 t += tstep;
  404.                 if (--spancount == 0)
  405.                     goto done;
  406.             case 2:
  407.                 *pdest++ = *(pbase + (s >> 16) + (t >> 16) * copy_of_cachewidth);
  408.                 s += sstep;
  409.                 t += tstep;
  410.                 if (--spancount == 0)
  411.                     goto done;
  412.             case 3:
  413.                 *pdest++ = *(pbase + (s >> 16) + (t >> 16) * copy_of_cachewidth);
  414.                 s += sstep;
  415.                 t += tstep;
  416.                 if (--spancount == 0)
  417.                     goto done;
  418.             case 0:
  419.                 break;
  420.             }
  421.             while (spancount >= 4)
  422.             {
  423.                 register unsigned long pixel;
  424.  
  425.                 pixel = *(pbase + (s >> 16) + (t >> 16) * copy_of_cachewidth);
  426.                 s += sstep;
  427.                 t += tstep;
  428.                 pixel = (pixel << 8) + *(pbase + (s >> 16) + (t >> 16) * copy_of_cachewidth);
  429.                 s += sstep;
  430.                 t += tstep;
  431.                 pixel = (pixel << 8) + *(pbase + (s >> 16) + (t >> 16) * copy_of_cachewidth);
  432.                 s += sstep;
  433.                 t += tstep;
  434.                 pixel = (pixel << 8) + *(pbase + (s >> 16) + (t >> 16) * copy_of_cachewidth);
  435.                 s += sstep;
  436.                 t += tstep;
  437.                 *(unsigned long *)pdest = pixel;
  438.                 pdest += 4;
  439.                 spancount -= 4;
  440.             }
  441.             switch (spancount) {
  442.             case 3:
  443.                 *pdest++ = *(pbase + (s >> 16) + (t >> 16) * copy_of_cachewidth);
  444.                 s += sstep;
  445.                 t += tstep;
  446.             case 2:
  447.                 *pdest++ = *(pbase + (s >> 16) + (t >> 16) * copy_of_cachewidth);
  448.                 s += sstep;
  449.                 t += tstep;
  450.             case 1:
  451.                 *pdest++ = *(pbase + (s >> 16) + (t >> 16) * copy_of_cachewidth);
  452.                 s += sstep;
  453.                 t += tstep;
  454.             case 0:
  455.                 break;
  456.             }
  457. done:
  458. #endif
  459.             s = snext;
  460.             t = tnext;
  461.  
  462.         } while (count > 0);
  463.  
  464.     } while ((pspan = pspan->pnext) != NULL);
  465. }
  466.  
  467. #endif
  468. //#endif
  469. #endif
  470.  
  471.  
  472. #if    !id386
  473. //#if    !idppc
  474. #if !id68k
  475.  
  476.  
  477. /*
  478. =============
  479. D_DrawSpans16
  480. =============
  481. */
  482. void D_DrawSpans16 (espan_t *pspan)
  483. {
  484.     int                count, spancount, copy_of_cachewidth;
  485.     unsigned char    *pbase, *pdest;
  486.     fixed16_t        s, t, snext, tnext, sstep, tstep;
  487.     float            sdivz, tdivz, zi, z, du, dv, spancountminus1;
  488.     float            sdivz16stepu, tdivz16stepu, zi16stepu;
  489.  
  490.     sstep = 0;    // keep compiler happy
  491.     tstep = 0;    // ditto
  492.  
  493.     pbase = (unsigned char *)cacheblock;
  494.  
  495.     sdivz16stepu = d_sdivzstepu * 16;
  496.     tdivz16stepu = d_tdivzstepu * 16;
  497.     zi16stepu = d_zistepu * 16;
  498.  
  499.     do
  500.     {
  501.         pdest = (unsigned char *)((byte *)d_viewbuffer +
  502.                 (screenwidth * pspan->v) + pspan->u);
  503.  
  504.         count = pspan->count;
  505.  
  506.     // calculate the initial s/z, t/z, 1/z, s, and t and clamp
  507.         du = (float)pspan->u;
  508.         dv = (float)pspan->v;
  509.  
  510.         sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
  511.         tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
  512.         zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
  513.         z = (float)0x10000 / zi;    // prescale to 16.16 fixed-point
  514.  
  515.         s = (int)(sdivz * z) + sadjust;
  516.         if (s > bbextents)
  517.             s = bbextents;
  518.         else if (s < 0)
  519.             s = 0;
  520.  
  521.         t = (int)(tdivz * z) + tadjust;
  522.         if (t > bbextentt)
  523.             t = bbextentt;
  524.         else if (t < 0)
  525.             t = 0;
  526.  
  527.         if (count > 16)
  528.             zi += zi16stepu;
  529.         else {
  530.             spancountminus1 = (float)(count - 1);
  531.             zi += d_zistepu * spancountminus1;
  532.         }
  533.         z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
  534.  
  535.         do
  536.         {
  537.         // calculate s and t at the far end of the span
  538.             if (count >= 16)
  539.                 spancount = 16;
  540.             else
  541.                 spancount = count;
  542.  
  543.             count -= spancount;
  544.  
  545.             if (count)
  546.             {
  547.             // calculate s/z, t/z, zi->fixed s and t at far end of span,
  548.             // calculate s and t steps across span by shifting
  549.                 sdivz += sdivz16stepu;
  550.                 tdivz += tdivz16stepu;
  551.                 snext = (int)(sdivz * z) + sadjust;
  552.                 tnext = (int)(tdivz * z) + tadjust;
  553.                 if (count > 16)
  554.                     zi += zi16stepu;
  555.                 else {
  556.                     spancountminus1 = (float)(count - 1);
  557.                     zi += d_zistepu * spancountminus1;
  558.                 }
  559.                 z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
  560.                 if (snext > bbextents)
  561.                     snext = bbextents;
  562.                 else if (snext < 16)
  563.                     snext = 16; // prevent round-off error on <0 steps from
  564.                            //  from causing overstepping & running off the
  565.                            //  edge of the texture
  566.  
  567.                 if (tnext > bbextentt)
  568.                     tnext = bbextentt;
  569.                 else if (tnext < 16)
  570.                     tnext = 16; // guard against round-off error on <0 steps
  571.  
  572.                 sstep = (snext - s) >> 4;
  573.                 tstep = (tnext - t) >> 4;
  574.             }
  575.             else
  576.             {
  577.             // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
  578.             // can't step off polygon), clamp, calculate s and t steps across
  579.             // span by division, biasing steps low so we don't run off the
  580.             // texture
  581.                 sdivz += d_sdivzstepu * spancountminus1;
  582.                 tdivz += d_tdivzstepu * spancountminus1;
  583.  
  584.                 snext = (int)(sdivz * z) + sadjust;
  585.                 tnext = (int)(tdivz * z) + tadjust;
  586.  
  587.                 if (snext > bbextents)
  588.                     snext = bbextents;
  589.                 else if (snext < 16)
  590.                     snext = 16; // prevent round-off error on <0 steps from
  591.                            //  from causing overstepping & running off the
  592.                            //  edge of the texture
  593.                 if (tnext > bbextentt)
  594.  
  595.                     tnext = bbextentt;
  596.                 else if (tnext < 16)
  597.                     tnext = 16; // guard against round-off error on <0 steps
  598.  
  599.                 if (spancount > 1)
  600.                 {
  601.                     sstep = (snext - s) / (spancount - 1);
  602.                     tstep = (tnext - t) / (spancount - 1);
  603.                 }
  604.             }
  605.  
  606.             copy_of_cachewidth = cachewidth;
  607. #if 1
  608.             do
  609.             {
  610.                 *pdest++ = *(pbase + (s >> 16) + (t >> 16) * copy_of_cachewidth);
  611.                 s += sstep;
  612.                 t += tstep;
  613.             } while (--spancount > 0);
  614. #else
  615.             switch (((unsigned long)pdest) & 3) {
  616.             case 1:
  617.                 *pdest++ = *(pbase + (s >> 16) + (t >> 16) * copy_of_cachewidth);
  618.                 s += sstep;
  619.                 t += tstep;
  620.                 if (--spancount == 0)
  621.                     goto done;
  622.             case 2:
  623.                 *pdest++ = *(pbase + (s >> 16) + (t >> 16) * copy_of_cachewidth);
  624.                 s += sstep;
  625.                 t += tstep;
  626.                 if (--spancount == 0)
  627.                     goto done;
  628.             case 3:
  629.                 *pdest++ = *(pbase + (s >> 16) + (t >> 16) * copy_of_cachewidth);
  630.                 s += sstep;
  631.                 t += tstep;
  632.                 if (--spancount == 0)
  633.                     goto done;
  634.             case 0:
  635.                 break;
  636.             }
  637.             while (spancount >= 4)
  638.             {
  639.                 register unsigned long pixel;
  640.  
  641.                 pixel = *(pbase + (s >> 16) + (t >> 16) * copy_of_cachewidth);
  642.                 s += sstep;
  643.                 t += tstep;
  644.                 pixel = (pixel << 8) + *(pbase + (s >> 16) + (t >> 16) * copy_of_cachewidth);
  645.                 s += sstep;
  646.                 t += tstep;
  647.                 pixel = (pixel << 8) + *(pbase + (s >> 16) + (t >> 16) * copy_of_cachewidth);
  648.                 s += sstep;
  649.                 t += tstep;
  650.                 pixel = (pixel << 8) + *(pbase + (s >> 16) + (t >> 16) * copy_of_cachewidth);
  651.                 s += sstep;
  652.                 t += tstep;
  653.                 *(unsigned long *)pdest = pixel;
  654.                 pdest += 4;
  655.                 spancount -= 4;
  656.             }
  657.             switch (spancount) {
  658.             case 3:
  659.                 *pdest++ = *(pbase + (s >> 16) + (t >> 16) * copy_of_cachewidth);
  660.                 s += sstep;
  661.                 t += tstep;
  662.             case 2:
  663.                 *pdest++ = *(pbase + (s >> 16) + (t >> 16) * copy_of_cachewidth);
  664.                 s += sstep;
  665.                 t += tstep;
  666.             case 1:
  667.                 *pdest++ = *(pbase + (s >> 16) + (t >> 16) * copy_of_cachewidth);
  668.                 s += sstep;
  669.                 t += tstep;
  670.             case 0:
  671.                 break;
  672.             }
  673. done:
  674. #endif
  675.             s = snext;
  676.             t = tnext;
  677.  
  678.         } while (count > 0);
  679.  
  680.     } while ((pspan = pspan->pnext) != NULL);
  681. }
  682.  
  683. #endif
  684. //#endif
  685. #endif
  686.  
  687.  
  688. #if    !id386
  689. #if    !idppc
  690. #if !id68k
  691.  
  692. /*
  693. =============
  694. D_DrawZSpans
  695. =============
  696. */
  697. void D_DrawZSpans (espan_t *pspan)
  698. {
  699.     int                count, doublecount, izistep;
  700.     int                izi;
  701.     short            *pdest;
  702.     unsigned        ltemp;
  703.     double            zi;
  704.     float            du, dv;
  705.  
  706. // FIXME: check for clamping/range problems
  707. // we count on FP exceptions being turned off to avoid range problems
  708.     izistep = (int)(d_zistepu * 0x8000 * 0x10000);
  709.  
  710.     do
  711.     {
  712.         pdest = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
  713.  
  714.         count = pspan->count;
  715.  
  716.     // calculate the initial 1/z
  717.         du = (float)pspan->u;
  718.         dv = (float)pspan->v;
  719.  
  720.         zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
  721.     // we count on FP exceptions being turned off to avoid range problems
  722.         izi = (int)(zi * 0x8000 * 0x10000);
  723.  
  724.         if ((long)pdest & 0x02)
  725.         {
  726.             *pdest++ = (short)(izi >> 16);
  727.             izi += izistep;
  728.             count--;
  729.         }
  730.  
  731.         if ((doublecount = count >> 1) > 0)
  732.         {
  733.             do
  734.             {
  735.                 ltemp = izi >> 16;
  736.                 izi += izistep;
  737.                 ltemp |= izi & 0xFFFF0000;
  738.                 izi += izistep;
  739.                 *(int *)pdest = ltemp;
  740.                 pdest += 2;
  741.             } while (--doublecount > 0);
  742.         }
  743.  
  744.         if (count & 1)
  745.             *pdest = (short)(izi >> 16);
  746.  
  747.     } while ((pspan = pspan->pnext) != NULL);
  748. }
  749.  
  750. #endif
  751. #endif
  752. #endif
  753.